use std::mem::replace;

/// An iterator that generates the Fibonacci sequence starting from `self.0` and `self.1`.
struct Fibnacci(u32, u32);

impl Iterator for Fibnacci {
    type Item = u32;

    fn next(&mut self) -> Option<Self::Item> {
        // `self.0` is the current Fibonacci number, `self.1` is the next Fibonacci number.
        // next <- self.0 <- self.1
        let next = replace(&mut self.0, self.1);

        // self.1 <- next + self.1
        self.1 += next;
        Some(next)
    }
}

pub fn odd_fibnacci_sum(threshold: u32) -> u32 {
    // For each Fibonacci number starting from 0 and 1 ...
    Fibnacci(0, 1)
        // ... and <= `threshold`, ...
        .take_while(|&x| x <= threshold)
        // ... filter out the odd ones ...
        .filter(|&x| x % 2 == 1)
        //... and sum them up.
        .sum()
}
